package gate

import (
	"errors"
	"fmt"
	"github.com/liu-junyong/go-logger/logger"
	"sync"
	. "../configs"
)

type TcpManager struct {
	mutex       sync.Mutex
	Connections []*TcpSession
	GateConfig  *GateConfigs
	Pm          *PlayerManager
}

//

func (this *TcpManager) Init(pm *PlayerManager) {
	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	this.Pm = pm
	this.GateConfig = GetConfigManger().GetGateConfigs()
	this.LoadConfig()
}

func (this *TcpManager) GetSessionUp(mapid int32) *TcpSession {
	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	this.mutex.Lock()
	defer this.mutex.Unlock()

	for _, v := range this.Connections {
		if "up" == v.Gt.Status {
			for _, k := range v.Gt.Map_id {
				if k == mapid {
					return v
				}
			}
		}
	}

	return nil
}

func (this *TcpManager) GetSessionByMapID(mapid int32) *TcpSession {
	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	this.mutex.Lock()
	defer this.mutex.Unlock()

	for _, v := range this.Connections {
		for _, k := range v.Gt.Map_id {
			if k == mapid {
				return v
			}
		}
	}

	return nil
}

func (this *TcpManager) GetSessionByURI(uri string, withlock bool) *TcpSession {
	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	if withlock {
		this.mutex.Lock()
		defer this.mutex.Unlock()
	}

	for _, v := range this.Connections {
		if v.Gt.Endpoint == uri {
			return v
		}
	}

	return nil
}

func (this *TcpManager) LoadConfig() {
	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	if this.GateConfig.GetConfigsLength() > 0 {
		go this.MergeConfig(this.GateConfig)
	} else {
		logger.Info("解析内容为空", this.GateConfig)
	}
}

func (this *TcpManager) MergeConfig(gt *GateConfigs) {
	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	for _, v := range gt.GetAllConfigs() {
		logger.Debug("add update server ->>> ", v)
		this.AddUpdateServer(v)
	}
}

func (this *TcpManager) AddUpdateServer(gt *GateNodeConfig) {
	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	this.mutex.Lock()
	defer this.mutex.Unlock()
	logger.Debug(gt.Endpoint, "创建连接中")
	connect := this.GetSessionByURI(gt.Endpoint, false)
	if connect != nil {
		connect.MergeStatus(gt)
		return
	}

	newsession := TcpSession{}
	newsession.Init(gt)

	this.Connections = append(this.Connections, &newsession)
	go newsession.Loop()

}

func (this *TcpManager) DisConnection(id string, reason string) {
	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	logger.Info(id, "断开连接", reason)
}

func (this *TcpManager) Checkkeepalive(gt *GateNodeConfig) {
	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	for _, v := range this.Connections {
		if v.Con != nil {
			if v.Status != 2 {
				go v.Init(gt)
			}

		}
	}
}

//
//
//enum TcpStatus
//{
//no_init = 0;
//connecting = 1;
//connected = 2;
//disconnected = 3;
//}

func (this *TcpManager) Send2backbyuri(uri string, clientid string, data string) error {
	connect := this.GetSessionByURI(uri, true)
	if connect != nil {
		err := connect.Send2BackJson(clientid, data)

		return err
	}
	return errors.New(fmt.Sprintf("找不到uri:%s clientid:%s msg:%s", uri, clientid, data))

}


